package steed.tag;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.jsp.tagext.TagSupport;

import steed.util.base.BaseUtil;
import steed.util.base.DevUtil;
import steed.util.base.IOUtil;
import steed.util.base.PathUtil;
import steed.util.base.RegUtil;
import steed.util.base.StringUtil;
import steed.util.reflect.ReflectUtil;

public abstract class BaseTag extends TagSupport{
	private static final Map<String, String> htmlCache = new HashMap<>();
	
	/**
	 * 获取tag/类名/fileName.html文件内容
	 * @param fileName 文件名,不用传后缀
	 * @return
	 */
	protected String getTagHtml(String fileName) {
		String filePath = getFilePath(fileName);
		if (htmlCache.get(filePath) == null) {
			String html = IOUtil.file2StringBuffer(new File(filePath), StringUtil.getCharacterSet()).toString();
			//TODO 压缩html
			htmlCache.put(filePath, html);
		}
		String evalEL = evalEL(htmlCache.get(filePath));
		if (DevUtil.devMode) {
			htmlCache.remove(filePath);
		}
		return evalEL;
	}

	/**
	 * 执行el表达式
	 * @return
	 */
	protected String evalEL(String str){
		if(str == null){
			return "";
		}
		//TODO 正则表达式匹配结果缓存
		Pattern pattern = RegUtil.getPattern("\\$\\{([^\\}]+)\\}");
		Matcher matcher = pattern.matcher(str);
		StringBuffer html = new StringBuffer(str);
		
		//偏移量
		int offset = 0;
		while(matcher.find()){
			String group = matcher.group(0);
			String el = matcher.group(1).trim();
			html.delete(matcher.start()+offset, matcher.end()+offset);
			String elValue = getELValue(el);
			html.insert(matcher.start()+offset, elValue);
			offset += elValue.length() - group.length();
		}
		
		return html.toString();
	}
	
	protected String getELValue(String elKey){
		//TODO 支持map,数组等带下标的el表达式,支持requestScope等前缀
		String[] keys = elKey.split("\\.");
		Object attribute = getAttribute(keys[0]);
		if (attribute == null) {
			return "";
		}
		if (keys.length > 1) {
			attribute = ReflectUtil.getChainValue(elKey.substring(keys[0].length()+1), attribute);
		}
		if (attribute == null) {
			attribute = "";
		}
		return attribute.toString();
	}
	
	protected Object getAttribute(String key) {
		Object attribute = pageContext.getRequest().getAttribute(key);
		if (attribute == null) {
			attribute = pageContext.getSession().getAttribute(key);
			if (attribute == null) {
				attribute = pageContext.getAttribute(key);
				if (attribute == null) {
					attribute = pageContext.getServletContext().getAttribute(key);
				}
			}
		}
		return attribute;
	}
	
	private String getFilePath(String fileName) {
		return PathUtil.getFormalClassesPath()+"/tag/"+StringUtil.firstChar2LowerCase(getClass().getSimpleName())+"/"+fileName+".html";
	}
	
	/**
	 * 写tag/类名/fileName.html文件内容到jsp
	 * @param fileName
	 */
	protected void writeFile(String fileName){
		write(getTagHtml(fileName));
	}
	
	protected void write(String str){
		try {
			pageContext.getOut().print(str);
		} catch (IOException e) {
			BaseUtil.getLogger().warn("写jsp出错!",e);
		}
	}
}
